home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / INFO / DOSTIPS2.ZIP / DOSFLTRS.TXT < prev    next >
Text File  |  1985-11-24  |  26KB  |  509 lines

  1.                       Designing DOS Filters
  2.   (PC Magazine Vol 3 No 20 Oct 16, 1984 M. Abrash/D. Illowsky)
  3.  
  4.      The most useful utility programs are not necessarily the
  5. most complex or powerful.  A simple utility can be very handy if
  6. it saves a few minutes a day, or if it lets you perform a needed
  7. function with a minimum of effort.  DOS versions 2.0 and higher
  8. provide three programs in the form of filters MORE, FIND and SORT
  9. that make it easy to manipulate data files and to pass information
  10. between programs.  Only a few filters are provided with PC-DOS,
  11. but new features, such as enhanced batch file processing and the
  12. redirection of I/O, make it a snap for you do design your own
  13. filter programs for various uses.
  14.      We present two "home-made" filters: one filter guarantees
  15. that all carriage returns in a file are paired with linefeeds,
  16. while the other ensures that a file has an end-of-file marker.
  17. These filters are elegantly simple and run with the speed of
  18. assembly language, and are fully functional and easy to use.
  19.      DOS 2.0 lets the user send input to a program from any file,
  20. just as if that input had been typed at the keyboard.  This is
  21. known as redirection of the standard input.  The standard input
  22. defaults to reading from the keyboard, but a less-than sign (<)
  23. on the command line is all that's required to redirect the standard
  24. input away from the keyboard.  For example, the command line:
  25.           LINK < LINKFILE.DAT
  26. runs the LINK program, taking the instructions for the linker from
  27. the file LINKFILE.DAT.
  28.      The standard output from any program -- that is, the
  29. interactive output that normally goes to the screen -- can likewise
  30. be redirected to any file by using a greater-than sign (>).  For
  31. instance, the command line:
  32.           TREE > SUBDIR.LST
  33. sends the list of all the subdirectories on the default disk to
  34. the file SUBDIR.LST.
  35.      For both input and output, the default standard device is
  36. the console device, CON:.  On input, the console is the keyboard,
  37. and on output, it is the video display.
  38.      A new feature introduced with DOS 2.0 is the filter.  A filter
  39. is a program that accepts information from the standard input,
  40. modifies that data in some way, and then sends the transformed
  41. information on to the standard output.  For example, the FIND
  42. filter, provided with DOS, accepts input from any text file and
  43. passes on to the standard output only those lines of text that
  44. contain the string of characters you specify.  This allows you
  45. to pick out certain lines of interest.  Either one or both of a
  46. filter's input and output may be redirected away from the console
  47. to any file.
  48.      You can visualize a filter as sitting between the standard
  49. input and standard output; it modifies the information passed
  50. from the input to the output according to a unique set of rules.
  51. As an example, you should look at one that filters all bare
  52. carriage returns into carriage return/linefeed (CR/LF) pairs.
  53.      Many users have been frustrated trying to use a file with
  54. only a bare carriage return marking the end of each line, rather
  55. than the CR/LF pair that most DOS programs require.  This problem
  56. is particularly common when working with files transferred from
  57. other computers via a modem or direct connection.  For example,
  58. files transferred from an Apple II typically contain no linefeeds
  59. and cannot be properly listed or used with most IBM software
  60. without being modified.  In fact, both EDLIN and WordStar treat
  61. such a file as if it consisted of one long line.
  62.      In the past, programs to fix files that contained bare
  63. carriage returns could be written in BASIC, but these were
  64. agonizingly slow.  Alternatively, such programs could be written
  65. in assembly language, but it was no small undertaking.  The
  66. redirection features and new functions provided by DOS 2.0 make it
  67. simple to design a compact, easy-to-use filter program that changes
  68. all bare carriage returns to CR/LF pairs with the speed of assembly
  69. language.  The great advantage of filters is that they make it easy
  70. to massage information as it passes between programs and to perform
  71. a whole series of file manipulations with a single command line.
  72.      A BASIC program is provided to create the filter program
  73. CRLF.COM.  The file CRLF.COM will be present on the default disk
  74. and ready for use.
  75.      To use the CR/LF filter, you redirect the input from the
  76. file with bare carriage returns and redirect the output to the
  77. file in which you want to store the corrected text.  If you do
  78. not redirect the output, the corrected text is displayed on the
  79. screen.  We strongly suggest that you don't filter a file back onto
  80. itself because this action simply destroys the original file.
  81.      For example, if you try to type file BARECR.TXT, which has a
  82. program listing with each line terminated with a bare carriage
  83. return, then each line will overwrite the previous line because
  84. there are no linefeeds to advance the cursor to the next row of
  85. the screen.  This is easily set right with the command line:
  86.           CRLF < BARECR.TXT
  87. When executed, this command reads all the characters from the
  88. file BARECR.TXT, changes all bare carriage returns to carriage
  89. return/linefeed pairs, and sends the corrected text to the screen
  90. which is the default standard output.  Because all carriage
  91. returns have been paired with linefeeds, the text will display
  92. legibly on separate lines.
  93.      Similarly, the command line:
  94.           CRLF < BARECR.TXT>CRLFPAIR.TXT
  95. takes input from the file BARECR.TXT, passes it through the CR/LF
  96. filter to correct all bare carriage returns, and sends the
  97. corrected text on to the file CRLFPAIR.TXT.  You can then use the
  98. file CRLFPAIR.TXT as you would any normal DOS file.
  99.      That's really all there is to using the CR/LF filter.  A
  100. single command line, with redirection of the standard input and
  101. output, ensures that every carriage return in any file is properly
  102. paired with a linefeed.  CR/LF works well with the piping features
  103. of DOS 2.0 as well.
  104.      One nice feature of the CR/LF filter is that any carriage
  105. return that is properly paired with a linefeed is left alone. You
  106. can filter either a normal file or one that has both bare and
  107. paired carriage returns, and no harm will be done to the carriage
  108. returns already paired.  However, some programs that set high
  109. bits may make linefeeds unrecognizable to CR/LF.  Files created by
  110. such programs should first be passed through another filter to
  111. strip the high bits.  Alternatively, you could modify CR/LF to
  112. ignore high bits.
  113.      Let's create a small file with only bare carriage returns so
  114. that we can see why the CR/LF filter is needed and how it works.
  115. Use the DEBUG program shown below to create the file TEXTCRLF.DAT
  116. on the default disk, containing four lines of text -- each
  117. terminated with a bare carriage return.  To verify that there are
  118. no linefeeds in this file, enter the command line:
  119.           TYPE TESTCRLF.DAT
  120. You will see that text lines display one atop the other, so only
  121. the last line is visible.  If you edit this file, you may find it
  122. does not display properly; EDLIN, for example, does not treat the
  123. lines as separate.
  124.      Now enter the command line:
  125.           CRLF < TESTCRLF.DAT
  126. to pass this file through the CR/LF filter and send it to the
  127. screen.  The file will display correctly because a linefeed is
  128. inserted at the end of each line.
  129.      To create a corrected version of the file TESTCRLF.DAT, you
  130. should enter the command line:
  131.           CRLF < TESTCRLF.DAT > CORRECTED.DAT
  132. The filtered output, with all carriage returns properly paired
  133. with linefeeds, is stored in the file CORRECTED.DAT.  You can edit
  134. or display this file as you would any normal text file.
  135.      The procedure is just as simple for any file of any size.
  136. Just redirect the input from the file that contains bare carriage
  137. returns and redirect the output to the file in which you want the
  138. corrected text to be placed.
  139.      A handy feature of the CR/LF filter is that it inserts an
  140. end-of-file (EOF) marker at the end of any file that lacks one.
  141. Ctrl-Z (value 26, or hexadecimal 1A) is generally used to mark
  142. the end of text files.  Most text editors and word processors
  143. look for this EOF marker when they load a file, but EDLIN is an
  144. exception to this rule.  However, not all files contain an end-
  145. of-file marker; for instance, files created with the COPY CON:
  146. command and those created with the DEBUG program lack the EOF
  147. marker.  If the marker is not present, most programs assume that
  148. all of the last sector of information read from the disk is a
  149. valid part of the file, but it is not.
  150.      If the character Ctrl-Z (hexadecimal 1A) is not the last
  151. byte of any file filtered with CR/LF, then a Ctrl-Z is added to
  152. the end of that file so that it can be edited properly.  For
  153. example, put a disk with space for a file in the default drive
  154. and enter the command lines:
  155.           COPY CON: NOEOF.DAT
  156.           THIS FILE IS NOT
  157.           TERMINATED WITH AN EOF MARKER
  158. and strike the F6 key.  The file NOEOF.DAT is now created, with
  159. no EOF marker.  To verify that the EOF marker is missing, edit
  160. NOEOF.DAT with your favorite word processor or editor (e.g.,
  161. WordStar), and you'll probably see a row of "@" characters at the
  162. bottom of the file.  These characters are garbage and do not
  163. properly belong in the file, but they are loaded because no EOF
  164. marker was present to tell the software where the file ended.
  165.      Now pass the file through the CR/LF filter with the command:
  166.           CRLF < NOEOF.DAT > ISEOF.DAT
  167. This creates the file ISEOF.DAT, which is identical to the file
  168. NOEOF.DAT except for a Ctrl-Z to mark the end of the file.  Then
  169. if you edit the file ISEOF.DAT, you will see that the garbage at
  170. the end of the file has been eliminated.
  171.      Because CR/LF can improperly modify files created by
  172. programs that set high bits, it is not an ideal tool for simply
  173. ensuring the EOF marker is present.  The BASIC program that creates
  174. the filter program MARKEOF.COM does nothing but add an EOF marker
  175. to the end of any file lacking one.
  176.      As an example of the use of the MARKEOF filter, you can place
  177. an EOF marker at the end of the NOEOF.DAT file that we created
  178. above with the command line:
  179.           MARKEOF < NOEOF.DAT > ISEOF.DAT
  180. Apart from the possible addition of a Ctrl-Z as an EOF marker, no
  181. change is made to the text of the filtered file.
  182.  
  183. Figure:  Creating TESTCRLF.DAT with DEBUG. If any response differs
  184.          from that shown (other than the segment address 6BF8),
  185.          exit with the "Q" command and start over.
  186.  
  187. A>DEBUG
  188. -F 100 L1C "LINE 1"0D "LINE 2" 0D "LINE 3" 0D "LINE 4" 0D
  189. -D100 11B
  190. 6BF8:0100  6C 69 6E 65 20 31 0D 6C-69 63 65 20 32 0D 6C 69
  191. 6BF8:0110  6E 65 20 33 0D 6C 69 6E-65 20 34 0D
  192. -RCX
  193. CX 0000
  194. :1C
  195. -RBX
  196. BX 0000
  197. :0
  198. -N TESTCRLF.DAT
  199. -W
  200. Writing 001C bytes
  201. -Q
  202. A>
  203.  
  204. -----------------------------------------------------------------
  205.                      Custom-Made DOS Filters
  206.   (PC Magazine Vol 3 No 21 Oct 30, 1984 M. Abrash/D. Illowsky)
  207.  
  208.      The design of the MARKEOF filter is simpler than the CR/LF
  209. filter's, so we'll examine its assembly language source code
  210. first (Figure 1).
  211.      The key to the MARKEOF filter is the use of the DOS functions
  212. 3F (hex) and 40 (hex).  Function 3F reads one or more characters,
  213. and function 40 writes one or more characters.  Each function is
  214. called by typing the number of bytes to be read in register CX,
  215. the location at which the bytes are to be placed in register DX,
  216. and the functin number in register AH.  Register BX has a file
  217. handle, which allows the device to be read from or written to.
  218. DOS lets you set up a file handle to refer to any file in any
  219. subdirectory, but we'll use only a small part of the file-handle
  220. feature.  DOS provides several built-in file handles that are
  221. always automatically available.  Two of these built-in file
  222. handles refer to the standard I/O, and that's all we need.
  223. If register BX contains 0 (for file-handle number zero), the
  224. standard input is used; if register BX contains 1, the standard
  225. output is used.  When registers, AH, BX, CX and DX are set, DOS
  226. is invoked to execute the function with software interrupt 21.
  227.      MARKEOF is interested in only the last character of the input
  228. file, so it just loops continually, passing characters from the
  229. standard input to the standard output, until the last character
  230. is reached; then an end-of-file marker is inserted if none is
  231. present.  This loop extends across lines 29 to 51 (Figure 1).
  232. (Line numbers are used only for explanatory purposes and should
  233. not be included when entering the program.)  Lines 30 through 36
  234. read a character from the standard input with function 3F.  Lines
  235. 43 through 49 immediately write the character to the standard
  236. output with functino 40.  This loop continues until function 3F
  237. returns a 0 in register AX, indicating that the standard input
  238. has no more text.
  239.      When the standard output runs out of text, MARKEOF checks on
  240. lines 57 through 60 to check the last character of the standard
  241. input.  If the character is Ctrl-Z (hex 1A), then the end of the
  242. file is properly marked, and MARKEOF is done.  If the character
  243. is not Ctrl-Z, then the end is unmarked, and a Ctrl-Z character
  244. is appended to the standard output by lines 65 through 71 so
  245. other programs will correctly detect the end of the file.  Finally,
  246. DOS function 4C (hex) ends MARKEOF and returns control to DOS.
  247.      The command sequence show in Figure 2 both assembles and links
  248. the file MARKEOF.ASM, as shown in Figure 1, into the executable
  249. filter program MARKEOF.COM.  You must have the IBM Macro Assembler
  250. (the program MASM.EXE) in order to assemble this program, and you
  251. will need to use the LINK and EXE2BIN programs provided with DOS.
  252. LINK will produce the error message "Warning: No STACK segment."
  253. This is of no concern, since the program uses the STACK segment
  254. set by DOS.
  255.      The assembler source listing for the CR/LF filter is shown
  256. in Figure 3.  The bulk of CR/LF is simply the loop from MARKEOF,
  257. in which each character is read from the standard input and sent
  258. to the standard output.  However, carriage returns are handled
  259. specially on lines 50 through 64.
  260.      After a carriage return has been sent to the standard output,
  261. a linefeed is automatically sent to the standard output as well.
  262. This ensures that all carriage returns are paired with linefeeds.
  263. Of course, if the next character from the standard input is a
  264. linefeed, which means that the carriage return was already
  265. paired, then there would be two linefeeds.  To avoid this, the
  266. character following the carriage return is read on line 54.
  267. If the next character is a linefeed, it is discarded; thus, the
  268. carriage return remains paired with a single linefeed.  If the
  269. next character is not a linefeed, then the carriage return was
  270. bare and now has been corrected, and, as a result, the next
  271. character is saved.
  272.      The pairing of every carriage return with only one linefeed
  273. is the sole difference between CR/LF and MARKEOF and is the only
  274. modification made to the text from the standard input as it flows
  275. through the filter.  When all the text has been filtered, lines
  276. 91 through 102 of Figure 3 guarantee that a Ctrl-Z is present to
  277. mark the end of the file.  Finally, DOS function 4C ends the
  278. program.
  279.      The command sequence shown in Figure 4 assembles and links
  280. the file CRLF.ASM, as shown in Figure 3, into the executable filter
  281. program named CRLF.COM.
  282.      After looking at the MARKEOF and CR/LF filters, you can see
  283. how easily a file can be modified with filters running under DOS
  284. 2.0 and how simple it is to make these filters.  With the new
  285. redirection features of DOS 2.0, filter programs can be written in
  286. assembly language without file control blocks, open and close
  287. functions, and complex function calls.  With DOS 2.0, even the
  288. neophyte assembly language programmer can easily design his own
  289. custom filter programs.
  290. - - - - - - - - - -
  291. Figure 1:  The assembly language listings for MARKEOF.
  292.  
  293. [1]  ;*
  294. [2]  ;* Assembly-language source code listing for MARKEOF,
  295. [3]  ;*   a filter to copy the standard input
  296. [4]  ;*   to the standard output, making sure that the
  297. [5]  ;*   text is terminated with Ctrl-Z (hex 1A) to
  298. [6]  ;*   mark the end of the file.
  299. [10] cseg   segment
  300. [11]        assume  cs:cseg,ds:cseg
  301. [12]        org     100h    ;COM files start at offset 100h
  302. [13] markeof        proc    far
  303. [14]        jmp     short read_char
  304. [16] ; Equates and storage area
  305. [18] eof    equ     lah     ;Ctrl-Z character that marks
  306. [19]                        ;  the end of a text file
  307. [20] tchar  db      ?       ;temporary storage for
  308. [21]                        ;  character read from standard input
  309. [22] end_of_file    db      eof  ;storage for end-of-file marker
  310. [24] ; Top of loop to read a character from the standard input
  311. [25] ;   and write it to the standard output.
  312. [26] ; Read the next character from the standard input.
  313. [29] read_char:
  314. [30]        sub     bx,bx   ;file handle for the standard input
  315. [31]        mov     cx,1    ;one character is to be read
  316. [32]        mov     dx,offset tchar  ;character read is to be
  317. [33]                                 ;  stored in tchar
  318. [34]        mov     ah,3fh  ;we want DOS function 3F (hex),
  319. [35]                        ;  which reads a character
  320. [36]        int     21h     ;invoke DOS to read a character
  321. [37]                        ;  from the standard input
  322. [38]        and     ax,ax   ;is the standard input out of text?
  323. [39]        jz      done    ;if so, then finish up
  324. [41] ; Write the character to the standard output.
  325. [43]        mov     bx,1    ;file handle for the standard output
  326. [44]        mov     cx,bx   ;one character is to be written
  327. [45]        mov     dx,offset tchar  ;character to be written is
  328. [46]                                 ;  stored in tchar
  329. [47]        mov     ah,40h  ;we want DOS function 40 (hex),
  330. [48]                        ;  which writes a character
  331. [49]        int     21h     ;invoke DOS to write a character
  332. [50]                        ;  to the standard output
  333. [51]        jmp     short read_char  ;read the next character
  334. [53] ; All text transferred - add an end of file marker
  335. [54] ;   exists.
  336. [56] done:
  337. [57]        cmp     [tchar],eof    ;was the last character read
  338. [58]                               ;  the end of file marker?
  339. [60]        jz      eof_set        ;if so, then we're done
  340. [62] ; The last character was not an end of file marker, so add
  341. [63] ;  the marker to the standard output.
  342. [65]        mov     bx,1     ;file handle for standard output
  343. [66]        mov     cx,bx    ;one character is to be written
  344. [67]        mov     dx,offset end_of_file   ;end-of-file marker 
  345. [68]                                        ;  to be written is
  346. [69]                                        ;  stored here
  347. [70]        mov     ah,40h   ;DOS function 40 (hex) to write
  348. [71]        int     21h      ;invoke DOS to write the end of file
  349. [72]                         ;  marker to the standard output
  350. [74] ; The end-of-file marker is all set, so we're done.
  351. [76] eof_set:
  352. [77]        mov     ah,4ch   ;DOS function 4C (hex) to terminate
  353. [78]        int     21h      ;invoke DOS to end the program
  354. [79] markeof        endp
  355. [80] cseg   ends
  356. [81]        end     markeof
  357. - - - - - - -
  358.  
  359. Figure 2:  Assemble, link and conversion steps for making the
  360.            source code of the filter MARKEOF, which is stored in
  361.            the file MARKEOF.ASM, into the runnable filter program
  362.            MARKEOF.COM.
  363.  
  364. A>MASM MARKEOF;
  365. The IBM Personal Computer MACRO Assembler
  366. Version 1.00 (C)Copyright IBM Corp 1981
  367.  
  368. Warning Severe
  369. Errors  Errors
  370. 0       0
  371.  
  372. A>LINK MARKEOF;
  373.  
  374. IBM Personal Computer Linker
  375. Version 2.00 (C)Copyright IBM Corp 1981, 1982, 1983
  376.  
  377. Warning: No STACK segment
  378.  
  379. There was 1 error detected
  380.  
  381. A>EXE2BIN MARKEOF.EXE MARKEOF.COM
  382.  
  383. A>ERASE MARKEOF.EXE
  384. - - - - - -
  385.  
  386. Figure 3:  The assembly language listings for the filter program
  387.            CR/LF.
  388.  
  389. [1]  ;* Assembly-language source code for CRLF, a filter to copy
  390. [2]  ;*   the standard input to the standard output, making sure
  391. [3]  ;*   that every carriage return is paired with a linefeed, 
  392. [4]  ;*   as with normal DOS files.  Also, Ctrl-Z (hex 1A) is
  393. [5]  ;*   added to mark the end of the file if no end-of-file
  394. [6]  ;*   marker is present.    
  395. [12] cseg   segment
  396. [13]        assume  cs:cseg,ds:cseg
  397. [14]        org     100h    ;COM files start at offset 100h
  398. [15] crlf   proc    far
  399. [16]        jmp     short read_char
  400. [18] ; Equates and storage area.
  401. [20] cr     equ     0dh     ;carriage return character
  402. [21] lf     equ     0ah     ;linefeed character
  403. [22] eof    equ     1ah     ;Ctrl-Z character
  404. [24] tchar  db      ?       ;temporary storage for character 
  405. [25]                        ;  read from standard input
  406. [26] linefeed       db      lf   ;storage for linefeed character
  407. [27] end_of_file    db      eof  ;storage for end-of-file marker
  408. [29] ; Top of loop to read a character from standard input and
  409. [30] ;   write it to the standard output, making sure that all
  410. [31] ;   carriage returns are paired with a linefeed.
  411. [33] read_char:
  412. [34]        call    read1   ;get the next character from
  413. [35]                        ;  the standard input
  414. [36] save_char:
  415. [37]        mov     dx,offset tchar  ;point to character read
  416. [38]        call    write1           ;write it to the standard
  417. [39]                                 ;  output
  418. [40]        cmp     [tchar],cr       ;was the character a CR?
  419. [42]        jz      handle_cr        ;if so, make sure it is 
  420. [43]                                 ;  paired with a linefeed
  421. [44]        jmp     short read_char  ;read the next character
  422. [46] ; Make sure that a CR is followed by a LF.
  423. [49] handle_cr:
  424. [50]        mov     dx,offset linefeed  ;point to the LF charactr
  425. [52]        call    write1           ;write a LF for the CR
  426. [54]        call    read1            ;get the next character, to
  427. [55]                                 ;  make sure the the CR was
  428. [56]                                 ;  not already paired with a
  429. [57]                                 ;  linefeed
  430. [59]        cmp     [tchar],lf       ;is the next character from
  431. [60]                                 ;  the standard input a LF?
  432. [62]        jnz     save_char        ;if it is not a LF, then 
  433. [63]                                 ;  then save it normally
  434. [64]        jmp     short read_char  ;if it is a LF, then read
  435. [65]                                 ;  the next character; the
  436. [66]                                 ;  LF just read is discarded
  437. [68] crlf   endup
  438. [70] ; Read the next character from the standard input, checking
  439. [71] ;  whether the standard input has run out of text.
  440. [74] read1  proc    near
  441. [75]        sub     bx,bx   ;file handle for the standard input
  442. [76]        mov     cx,1    ;one character is to be read
  443. [77]        mov     dx,offset tchar  ;character read is to be
  444. [78]                                 ;  stored in tchar
  445. [79]        mov     ah,3fh  ;we want DOS function 3F (hex),
  446. [80]                        ;  which reads a character
  447. [81]        int     21h     ;invoke DOS to read a character from
  448. [82]                        ;  the standard input
  449. [83]        and     ax,ax   ;is the standard input out of text?
  450. [84]        jz      done    ;if so, then finish up
  451. [85]        ret
  452. [87] ; All text transferred - add an EOF marker if none exists
  453. [90] done:
  454. [91]        cmp     [tchar],eof    ;was the last character read
  455. [92]                               ;  the EOF marker?
  456. [94]        jz      eof_set        ;if so, then we're done
  457. [96] ; The last character was not an EOF marker, so add the 
  458. [97] ;  marker to the standard output.
  459. [99]        mov     dx,offset end_of_file   ;EOF marker to be
  460. [100]                                       ;  written is stored
  461. [101]                                       ;  here
  462. [102]       call    write1                  ;write the EOF marker
  463. [104] ; The EOF marker is all set, so we're done.
  464. [106] eof_set:
  465. [107]       mov     ah,4ch   ;DOS function 4C to terminate
  466. [108]       int     21h      ;invoke DOS to end the program
  467. [109] read1 endup
  468. [111] ; Write the chracter pointed to by register DX to the 
  469. [112] ;   standard output.
  470. [114] write1  proc  near
  471. [115]       mov     bx,1    ;file handle for the standard output
  472. [116]       mov     cx,bx   ;one character is to be written
  473. [117]       mov     ah,40h  ;we want DOS function 40 which
  474. [118]                       ;  writes a character
  475. [119]       int     21h     ;invoke DOS to write a character to
  476. [120]                       ;  the standard output
  477. [121]       ret
  478. [122] write1  endp
  479. [123] cseg    ends
  480. [124]         end   crlf
  481. - - - - - - -
  482.  
  483. Figure 4:  Assemble, link and conversion steps for making the
  484.            source code of the filter CR/LF, which is stored in
  485.            the file CRLF.ASM, into the runnable filter program
  486.            CRLF.COM.
  487.  
  488. A>MASM CRLF;
  489. The IBM Personal Computer MACRO Assembler
  490. Version 1.00 (C)Copyright IBM Corp 1981
  491.  
  492.  
  493. Warning Severe
  494. Errors  Errors
  495. 0       0
  496.  
  497. A>LINK CRLF;
  498.  
  499. IBM Personal Computer Linker
  500. Version 2.00 (C)Copyright IBM Corp 1981, 1982, 1983
  501.  
  502. There was 1 error detected
  503.  
  504. A>EXE2BIN CRLF.EXE CRLF.COM
  505.  
  506. A>ERASE CRLF.EXE
  507.  
  508. -----------------------------------------------------------------
  509.